package top.codingfly.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import top.codingfly.service.IRedisLockService;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * @Date: 2022/12/29
 * @Desc:
 */
@Slf4j
@Service
public class RedisLockServiceImpl implements IRedisLockService {

    @Resource
    public RedissonClient redissonClient;

    /**
     * 获取分布式锁
     * @param lockKey 锁
     * @param waitMilliseconds 获取锁的等待时间，单位毫秒
     * @param expireMilliseconds 锁的过期时间，单位毫秒
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, long waitMilliseconds, long expireMilliseconds) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            return lock.tryLock(waitMilliseconds, expireMilliseconds, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 解锁 - 重入的方式，所以同一个线程加了几次锁就要释放几次锁
     * @param lockKey 锁的值
     */
    public void releaseLock(String lockKey) {
        try {
            RLock lock = redissonClient.getLock(lockKey);
            if (null != lock && lock.isHeldByCurrentThread()) { //判断锁是否存在，和是否当前线程加的锁。
                lock.unlock();
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            log.error("解锁 {} 失败", lockKey);
        }
    }

}
